﻿using log4net;
using Renci.SshNet.Messages;
using ServerControl.Model;
using ServerControl.Model.Enum;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Web.UI.WebControls;

namespace ServerControl.Dal
{
    public class CommentDal : DbBase
    {
        private static ILog logger = LogManager.GetLogger("CommentDal");
        private static object lockObj = new object();//定义线程锁

        public static bool Insert(Comment comment)
        {
            return Instance.Insertable(comment).ExecuteCommand() > 0;
        }

        public static bool Delete(string userName, List<int> ids)
        {
            return Instance.Deleteable<Comment>().Where(t => t.UserName == userName && ids.Contains(t.Id)).ExecuteCommand() > 0;
        }

        public static List<Comment> Select(string userName, List<int> ids)
        {
            return Instance.Queryable<Comment>().Where(t => t.UserName == userName && ids.Contains(t.Id)).ToList();
        }

        public static List<Comment> SelectByVideoIds(string userName, List<int> videoIds)
        {
            return Instance.Queryable<Comment>().Where(t => t.UserName == userName && videoIds.Contains(t.VideoId)).ToList();
        }

        public static bool Update(Comment comment)
        {
            return Instance.Updateable(comment).IgnoreColumns(t => new { t.UserName, t.AddTime, t.CommentTime, t.UniqueId, t.NickName, t.ClientName }).ExecuteCommand() > 0;
        }

        public static List<Comment> ListPage(ref int records,
            int page,
            int limit,
            string userName,
            int videoId = 0,
            string uniqueId = "",
            string nickName = "",
            ContentTypeEnum contentType = ContentTypeEnum.All,
            CommentStatusEnum commentStatus = CommentStatusEnum.All,
            string clientName = "")
        {
            return Instance
                .Queryable<Comment>()
                .Where(t => t.UserName == userName)
                .WhereIF(videoId > 0, t => t.VideoId == videoId)
                .WhereIF(!string.IsNullOrEmpty(uniqueId), t => t.UniqueId == uniqueId)
                .WhereIF(!string.IsNullOrEmpty(nickName), t => t.NickName == nickName)
                .WhereIF(contentType != ContentTypeEnum.All, t => t.ContentType == contentType)
                .WhereIF(commentStatus == CommentStatusEnum.Commented, t => t.AddTime != t.CommentTime)
                .WhereIF(commentStatus == CommentStatusEnum.UnCommented, t => t.AddTime == t.CommentTime)
                .WhereIF(!string.IsNullOrEmpty(clientName), t => t.ClientName == clientName)
                .ToPageList(page, limit, ref records);
        }


        public static Comment Select(ref Account account, string userName, string clientName)
        {
            Comment comment = null;
            account = null;

            lock (lockObj)
            {
                var instance = Instance;
                instance.BeginTran();

                try
                {
                    var isSuccess = true;
                    comment = Instance.Queryable<Comment>().Where(t => t.UserName == userName && t.ClientName == clientName && t.AddTime == t.CommentTime).First();

                    if (comment == null)
                    {
                        comment = Instance.Queryable<Comment, Account>((c, a) => new JoinQueryInfos(JoinType.Inner, 1 == 1))
                            .Where((c, a) => c.UserName == userName && string.IsNullOrEmpty(c.ClientName) && c.AddTime == c.CommentTime && a.Cookies != "")
                            .OrderBy(c => new { c.AddTime }, OrderByType.Asc)
                            .OrderBy((c, a) => SqlFunc.GetRandom())
                            .Select((c, a) => new Comment
                            {
                                Id = c.Id,
                                VideoId = c.VideoId,
                                Content = c.Content,
                                ContentType = c.ContentType,
                                UserName = c.UserName,
                                AddTime = c.AddTime,
                                CommentTime = c.CommentTime,
                                UniqueId = a.UniqueId,
                                NickName = a.NickName,
                                ClientName = c.ClientName
                            })
                            .First();

                        if (comment != null)
                        {
                            account = instance.Queryable<Account>().Where(t => t.UserName == userName && t.UniqueId == comment.UniqueId).First();
                            isSuccess = instance.Updateable<Comment>().SetColumns(t => new Comment { ClientName = clientName, UniqueId = comment.UniqueId, NickName = comment.NickName })
                                .Where(t => t.Id == comment.Id).ExecuteCommand() > 0;
                        }
                    }
                    else
                    {
                        account = instance.Queryable<Account>().Where(t => t.UserName == userName && t.UniqueId == comment.UniqueId).First();
                    }

                    if (isSuccess && account != null)
                    {
                        instance.CommitTran();
                    }
                    else
                    {
                        comment = null;
                        account= null;
                        instance.RollbackTran();
                    }
                }
                catch (Exception ex)
                {
                    comment = null;
                    account = null;
                    instance.RollbackTran();
                    logger.Error(ex);
                }
            }

            return comment;
        }

        public static bool Release(string userName, int id)
        {
            return Instance
                .Updateable<Comment>()
                .SetColumns(t => new Comment { UniqueId = "", NickName = "", ClientName = "" }).Where(t => t.UserName == userName && t.Id == id)
                .ExecuteCommand() > 0;
        }

        public static bool UpdateComment(string userName, int id)
        {
            return Instance
                .Updateable<Comment>()
                .SetColumns(t => t.CommentTime == DateTime.Now).Where(t => t.UserName == userName && t.Id == id)
                .ExecuteCommand() > 0;
        }
    }
}
